﻿using PayPal.PayPalAPIInterfaceService;
using PayPal.PayPalAPIInterfaceService.Model;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web;

namespace DTcms.API.Payment.paypal
{
    /// <summary>
    /// 提交支付
    /// </summary>
    public class PaypalSumbit
    {
        /// <summary>
        /// 订单支付
        /// </summary>
        /// <param name="number">商品名称</param>
        /// <param name="goodsname">商品名称</param>
        /// <param name="price">价格</param>
        /// <param name="currency">货币</param>
        /// <param name="quantity">数量</param>
        /// <param name="cancelUrl">取消地址（选填）</param>
        public string Sumbit(string number, string goodsname, string price, string currency, string quantity)
        {
            string payToken = GetPayToken(number, goodsname, price, currency, quantity);
            string redirectUrl = PaypalConfig.RedirectUrl;
            return redirectUrl + payToken;
        }

        /// <summary>
        /// 获取支付地址（支付令牌）
        /// </summary>
        /// <param name="payToken"></param>
        /// <returns></returns>
        public string GetPayUrlByToken(string payToken)
        {
            string redirectUrl = PaypalConfig.RedirectUrl;
            return redirectUrl + payToken;
        }

        /// <summary>
        /// 获取支付token
        /// </summary>
        /// <param name="number"></param>
        /// <param name="goodsname"></param>
        /// <param name="price"></param>
        /// <param name="currency"></param>
        /// <param name="quantity"></param>
        /// <returns></returns>
        public string GetPayToken(string number, string goodsname, string price, string currency, string quantity)
        {
            string returnUrl = PaypalConfig.ReturnUrl.Replace("|orderno|", number);
            string cancelUrl = PaypalConfig.CancelUrl.Replace("|orderno|", number);


            int nums;
            if (Int32.TryParse(quantity, out nums) == false)
                nums = 1;

            CurrencyCodeType currencycode; //货币

            if (!Enum.TryParse<CurrencyCodeType>(currency, out currencycode))
                currencycode = CurrencyCodeType.USD;

            PayPalAPIInterfaceServiceService sservice = PaypalConfig.GetPayService();

            //付款明细项目
            var paymentDetailsItem = new List<PaymentDetailsItemType>();
            paymentDetailsItem.Add(new PaymentDetailsItemType()
            {
                Name = goodsname,
                Quantity = nums,
                Amount = new BasicAmountType(currencycode, price),
                ItemCategory = ItemCategoryType.PHYSICAL,
                Number = number
            });

            //付款明细
            var paymentDetails = new List<PaymentDetailsType>();
            paymentDetails.Add(new PaymentDetailsType()
            {
                PaymentAction = PaymentActionCodeType.SALE,
                OrderTotal = new BasicAmountType(CurrencyCodeType.USD, (Convert.ToDecimal(price) * nums).ToString("0.00")),
                PaymentDetailsItem = paymentDetailsItem,
                Custom = number
            });

            //设置快速签出请求详细信息
            var setExpressCheckoutRequestDetails = new SetExpressCheckoutRequestDetailsType()
            {
                ReturnURL = returnUrl,
                CancelURL = cancelUrl,
                PaymentDetails = paymentDetails,
                CustomerServiceNumber = number
            };

            //设置快速签出请求
            var setExpressCheckoutRequest = new SetExpressCheckoutRequestType()
            {
                Version = "104.0",
                SetExpressCheckoutRequestDetails = setExpressCheckoutRequestDetails
            };

            var setExpressCheckoutReq = new SetExpressCheckoutReq()
            {
                SetExpressCheckoutRequest = setExpressCheckoutRequest
            };

            SetExpressCheckoutResponseType response = sservice.SetExpressCheckout(setExpressCheckoutReq);

            if (response.Ack == AckCodeType.SUCCESS || response.Ack == AckCodeType.SUCCESSWITHWARNING)
            {
                return response.Token;
            }
            else
            {
                StringBuilder sbErrMsg = new StringBuilder();
                response.Errors.ForEach(error =>
                {
                    sbErrMsg.AppendFormat("ErrorCode:{0}\r\nShortMessage:{1}\r\nLongMessage:{2}\r\n", error.ErrorCode, error.ShortMessage, error.LongMessage);
                });
                throw new Exception(sbErrMsg.ToString());
            }
        }
    }
}
